﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.ServiceModel.Syndication;
using System.Speech.Recognition;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Xml;

namespace DigiMate
{
	
	public class NewsService: BaseService
	{
		private DateTime lastDate = DateTime.Now.Date;
		private bool onPause = false;
		public static string Details = "details";
		public static string Stop = "stop";
		public static string Yes = "Da";
		public static string No = "Niet";
		private System.Threading.Timer timer;
		public static volatile int dldnow;

		private bool OnPause
		{
			get { return onPause; }
			set
			{
				onPause = value;
				if (onPause)
				{
					if (inProcess)
						AddLog("Stop pendind...");
					else
						AddLog("Stopped");
				}
			}
		}

		protected override bool IsAsync
		{
			get
			{
				return false;
			}
		}

		public NewsService()
		{
			int CheckInterval = Convert.ToInt32(System.Configuration.ConfigurationManager.AppSettings["CheckInterval"]); // minutes!
			//timer = new System.Threading.Timer(new TimerCallback(elapsed), dldnow, 1000 * 1, 1000 * 60 * CheckInterval);
		}


		public void elapsed(object obj)
		{
			ReadRss(false);
		}


		public void ReadRss(bool forceStart)
		{
			if (forceStart)
				OnPause = false;

			// This method runs asynchronously.
			ReadRss();

			AddLog("Done");
		}

		protected override Grammar GetGrammar()
		{
			GrammarBuilder grammarBuilder = new GrammarBuilder();
			grammarBuilder.Culture = reco.RecognizerInfo.Culture;
			grammarBuilder.Append(new Choices(NewsService.Details, NewsService.Stop, NewsService.Yes, NewsService.No));
			return new Grammar(grammarBuilder);
		}

		public override void Run(string text)
		{
			//await Task.Run(() => ReadRss(true));
			//ReadRss();
			ReadRss(true);
		}

		private void ReadRss()
		{
			try
			{
				DigiMate.AnyServiceActive = true;
				
				if (inProcess)
					return;

				inProcess = true;
				
				string url = System.Configuration.ConfigurationManager.AppSettings["RssURL.News"]; ;
				XmlReader reader = XmlReader.Create(url);
				SyndicationFeed feed = SyndicationFeed.Load(reader);
				reader.Close();

				bool firstTime = true;
				var feedList = feed.Items.Where(x => x.PublishDate.DateTime > lastDate).OrderBy(x => x.PublishDate);
				if (feedList.Count() > 0)
				{
					foreach (SyndicationItem item in feedList)
					{
						if (OnPause)
							break;

						//CheckForQuit();

						if (firstTime)
						{
							string msg = "Есть " + feedList.Count() + " новостей! Хотите прочитаю?";
							AddLog(msg);
							Speaker.Speak(msg);
							firstTime = false;

							Thread.Sleep(500);


							RecognitionResult res = reco.Recognize(TimeSpan.FromMilliseconds(3000)); // recognize speech
							bool shouldRead = false;

							if (res != null && res.Words.Count > 0)
							{
								if (res.Words[0].Text.ToLower() == NewsService.No.ToLower())
								{
									AddLog("No - command received");
									Speaker.Speak("Ok, прекращаю.");
									break;
								}
								else if (res.Words[0].Text.ToLower() == NewsService.Yes.ToLower())
								{
									AddLog("Yes - command received");
									Speaker.Speak("Ok, Слушайте.");
									shouldRead = true;
								}
								
							}
							if (!shouldRead)
							{
								Speaker.Speak("Не буду зачитывать..");
								break;
							}

						}

						if (lastDate < item.PublishDate.DateTime)
						{
							String subject = item.Title == null ? "" : item.Title.Text;
							String summary = item.Summary == null ? "no details" : item.Summary.Text;
							DateTime date = item.PublishDate.DateTime;

							if (subject == "")
								continue;

							Speaker.SpeakOk(subject);

							//CheckForQuit();
							if (OnPause)
								break;

							lastDate = item.PublishDate.DateTime;

							//reco.RecognizeAsync(RecognizeMode.Multiple); // recognize speech
							//Console.Beep();

							if (reco != null)
							{
								AddLog("waiting for command..");
								Thread.Sleep(500);

								RecognitionResult res = reco.Recognize(TimeSpan.FromMilliseconds(2000)); // recognize speech

								if (res != null && res.Words.Count > 0)
								{
									if (res.Words[0].Text.ToLower() == NewsService.Details.ToLower())
									{
										AddLog("Details - command received");
										Speaker.SpeakOk("Details");
										Speaker.Speak(summary.Length > cutLongSummaryTo ? summary.Substring(0, cutLongSummaryTo) : summary);
									}
									else if (res.Words[0].Text.ToLower() == NewsService.Stop.ToLower())
									{
										AddLog("Stop command received");
										Speaker.SpeakOk("Yes sir, I will stop till next time");
										break;
									}
									else
										AddLog("Commands not detected..");

								}
							}

							//CheckForQuit();

							Thread.Sleep(1000);
						}
					}
					Speaker.Speak("Это все новости на данный момент");
				}
				else
				{
					AddLog("No new messages in RSS");
					Speaker.Speak("Свежих новостей не нашла");
				}
			}
			catch (Exception ex)
			{
				AddLog("There was a problem with rss: " + ex.Message);
			}
			finally
			{
				if (OnPause)
					AddLog("Stopped.");

				inProcess = false;
				//DigiMate.AnyServiceActive = false;
			}
		}
	}
}
